package com.zengqingfa.springboot.validation.demo.controller;

import com.zengqingfa.springboot.validation.demo.dto.ListValueValidatorDTO;
import com.zengqingfa.springboot.validation.demo.dto.UserCollectionDTO;
import com.zengqingfa.springboot.validation.demo.dto.UserNestedDTO;
import com.zengqingfa.springboot.validation.demo.dto.UserParentCollectionDTO;
import com.zengqingfa.springboot.validation.demo.entity.User;
import com.zengqingfa.springboot.validation.demo.util.ValidableList;
import com.zengqingfa.springboot.validation.demo.util.ValidateUtility;
import com.zengqingfa.springboot.validation.demo.util.ValidationList;
import org.hibernate.validator.constraints.Length;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.groups.Default;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author zengqingfa
 * @date 2019/11/22 15:31
 * @description
 * @email zengqingfa_java@163.com
 */
@RestController
@RequestMapping("/user")
@Validated
public class UserController {

    @RequestMapping("/save")
    public String saveUser(@RequestBody @Valid User user, BindingResult result, HttpServletResponse response) {
        return ValidateUtility.judgeValidate(result, response);
    }


    @PostMapping("/requestBody")
    public String requestBody(@RequestBody @Validated UserNestedDTO userDTO) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    @PostMapping("/requestBody2")
    public String requestBody2(@RequestBody @Valid UserNestedDTO userDTO) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }


    @GetMapping("/pathVariable/{userId}")
    public String pathVariable(@PathVariable("userId") @Min(100L) Long userId) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    @GetMapping("/queryParam")
    public String queryParam(@Length(min = 6, max = 20) @NotEmpty String account) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    @PostMapping("/nestedValid")
    public String nestedValid(@RequestBody @Valid UserNestedDTO userNestedDTO) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    @PostMapping("/collectionValid")
    public String collectionValid(@RequestBody @Validated List<UserCollectionDTO> list) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    @PostMapping("/collectionValid2")
    public String collectionValid2(@RequestBody @Valid ValidationList<UserCollectionDTO> list) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }


    @PostMapping("/collectionValid3")
    public String collectionValid3(@RequestBody @Valid ValidableList<UserCollectionDTO> list) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    @PostMapping("/collectionValid4")
    public String collectionValid4(@RequestBody @Valid UserParentCollectionDTO dto) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    @PostMapping("/collectionValid5")
    public String collectionValid5(@RequestBody @Validated List<UserCollectionDTO> list) {
        //单独校验
        for (UserCollectionDTO user : list) {
            Set<ConstraintViolation<UserCollectionDTO>> set = validator.validate(user, Default.class);
            if (set != null && !set.isEmpty()) {
                for (ConstraintViolation cv : set) {
                    throw new RuntimeException(cv.getPropertyPath()+cv.getMessage());
                }
            }
        }
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }

    @GetMapping("/notEmptyValid")
    public String notEmptyValid(@NotEmpty String userCode) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }


    @PostMapping("/listValueValidator")
    public String listValueValidator(@RequestBody @Valid ListValueValidatorDTO dto) {
        // 校验通过，才会执行业务逻辑处理
        return "ok";
    }
}
